package screen;

import java.util.Hashtable;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import net.rim.device.api.i18n.SimpleDateFormat;
import net.rim.device.api.system.Application;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.DeviceInfo;
import net.rim.device.api.system.PersistentObject;
import net.rim.device.api.system.PersistentStore;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.FullScreen;
import net.rim.device.api.ui.container.MainScreen;
import weibo.Oauth;
import weibo.http.AccessToken;
import weibo.model.WeiboException;
import code.AccessTokenSettings;
import code.Function;

public class SplashScreen extends FullScreen
{
	private static PersistentObject _store;
	private static Vector _data;
	private static Vector _dataOauth2AccessToken;

	private AccessToken accessToken;
	private Hashtable _authorizeCode;
	
	private MainScreen nextScreen;
	private UiApplication application;
	private Timer timer=new Timer();
	
    private ConnectionThread _connectionThread = new ConnectionThread();
    
	public SplashScreen(UiApplication uiApplication)
	{
		super(NO_VERTICAL_SCROLL | NO_SYSTEM_MENU_ITEMS | USE_ALL_HEIGHT);

		if(!_connectionThread.isStarted()) {_connectionThread.start();}
		
		application=uiApplication;

		add(new BitmapField(Bitmap.getBitmapResource("splash.png"), LabelField.VCENTER | LabelField.HCENTER));

		application.pushScreen(this);
		
		if(DeviceInfo.isSimulator())
		{
			accessToken=new AccessToken();
			accessToken.setToken("2.004pqn3ChXgiNBbafb9169710eW1qh");     //Access Token
			accessToken.setUid("2169226201");    //UID
	    	
	    	_connectionThread.fetch();
		} else {
			if(_dataOauth2AccessToken.size()>0)
			{
				AccessTokenSettings setttings=(AccessTokenSettings) _dataOauth2AccessToken.elementAt(0);
				
				accessToken=new AccessToken();
				accessToken.setToken(setttings.getToken());
				accessToken.setUid(setttings.getUid());
				accessToken.setExpiresTime(setttings.getExpiresTime());
				
		    	UiApplication.getUiApplication().invokeLater(new Runnable()
		    	{
					public void run()
					{
						if(!accessToken.validateToken())
						{
							Function.errorDialog("用户授权已到期，正在重新授权，请根据屏幕提示继续操作....");
						
							try {
								startAuthorize();
							
								_connectionThread.fetch();
							} catch (WeiboException e) {Function.errorDialog(e.toString());}
						} else {_connectionThread.fetch();}
					}
		    	});
			} else {
		    	UiApplication.getUiApplication().invokeLater(new Runnable()
		    	{
					public void run()
					{
				    	try {
							startAuthorize();
							
					    	_connectionThread.fetch();
						} catch (WeiboException e) {Function.errorDialog(e.toString());}
					}
				});
			}
		}
	}

    public void startAuthorize() throws WeiboException
	{
    	accessToken=null;
    	_authorizeCode=null;
    	Oauth oauth = new Oauth();
		WeiboAuthorizeScreen weiboDialog=new WeiboAuthorizeScreen(oauth.authorize("code", ""));
		UiApplication.getUiApplication().pushModalScreen(weiboDialog);
		_authorizeCode=weiboDialog.getAccessToken();
		weiboDialog=null;
		
		if (accessToken==null && !_authorizeCode.isEmpty())
		{
			accessToken=oauth.getAccessTokenByCode(_authorizeCode.get("code").toString());

			if(!accessToken.isSessionValid())
			{
				Function.errorDialog("1: Falied to receive access token, application will be exit now.");
				
				System.exit(0);
			} else {
				synchronized(Application.getEventLock())
				{
					application.invokeLater(new Runnable()
					{
						public void run()
						{
							SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm");
							add(new LabelField("微博授权成功！"));
							add(new LabelField("授权到期时间："+sdf.formatLocal(accessToken.getExpiresTime())));
						}
					});
					
					saveData();
				}
			}
		} else {
			Function.errorDialog("2: Falied to receive access token, application will be exit now.");
			
			System.exit(0);
		}
	}
    
	public void dismiss()
	{
		application.popScreen(this);
		application.pushScreen(nextScreen);
	}
	
	private class CountDown extends TimerTask
	{
		public void run()
		{
			DismissThread dThread=new DismissThread();
			application.invokeLater(dThread);
		}
	}
	
	private class DismissThread implements Runnable
	{
		public void run() {dismiss();}
	}

	private void saveData()
	{
		AccessTokenSettings settings=new AccessTokenSettings();
		
		settings.setToken(accessToken.getToken());
		settings.setExpireIn("");
		settings.setUid(accessToken.getUID());
		settings.setExpiresTime(String.valueOf(accessToken.getExpiresTime()));
		
		boolean updated=false;
		
		for(int i=0; i<_data.size(); i++)
		{
			if(_data.elementAt(i) instanceof AccessTokenSettings)
			{
				_data.setElementAt(settings, i);
					
				i=_data.size()+1;
				updated=true;
			}
		}

		if(!updated) {_data.addElement(settings);}	
		
		synchronized(_store)
		{
			_store.setContents(_data);
			_store.commit();
		}	
	}
	
	static
   	{
   		_store=PersistentStore.getPersistentObject(0xf9f469f8b9543bc5L); //blackberry_weibo_authorize_token
   		
   		synchronized(_store)
   		{
   			if(_store.getContents()==null)
   			{
   				_store.setContents(new Vector());
   				_store.forceCommit();
   			}
   		}
   		
   		try {
			_dataOauth2AccessToken=new Vector();
			_data=new Vector();
			_data=(Vector) _store.getContents();
			
	    	for(int i=0; i<_data.size(); i++)
	    	{
	    		if(_data.elementAt(i) instanceof AccessTokenSettings)
	    		{
	    			_dataOauth2AccessToken.addElement(_data.elementAt(i));
	    		}
	    	}
		} catch (final Exception e) {}
   	}
	
	public boolean onClose()
	{
		_connectionThread.stop();
		
		return super.onClose();
	}
	
	class ConnectionThread extends Thread
    {
        private static final int TIMEOUT = 1000;
        
        private volatile boolean _fetchStarted = false;
        private volatile boolean _stop = false;

        private boolean isStarted() {return _fetchStarted;}            
        private void fetch() {_fetchStarted = true;}
        private void stop() {_stop = true;}

        public void run()
        {
            for(;;)
            {
                while( !_fetchStarted && !_stop)  
                {
                    try {sleep(TIMEOUT);} catch (InterruptedException e) {Function.errorDialog("Thread#sleep threw " + e.toString());}
                }
                
                if(_stop) {return;}

                try {
	                nextScreen=new WeiboScreen(accessToken);
				} catch (WeiboException e) {}
                
                _fetchStarted = false;

                UiApplication.getUiApplication().invokeLater(new Runnable()
                {
					public void run() {stop(); dismiss();}
				});

                stop();
            }
        }
    }
}